/**
 * 微信登录错误处理工具
 */

// 微信登录错误码映射
export const WECHAT_ERROR_CODES = {
  // 后端错误码
  1_100_021_000: '微信授权失败，请重试',
  1_100_021_001: '微信授权码无效，请重新登录',
  1_100_021_002: '微信用户数据解密失败',
  1_100_021_003: '微信用户信息无效',
  1_100_021_004: '微信账号绑定失败',

  // HTTP状态码
  400: '请求参数错误',
  401: '微信授权失败，请重试',
  403: '访问被拒绝',
  404: '服务不存在',
  500: '服务器内部错误',
  502: '网关错误',
  503: '服务暂时不可用',
  504: '请求超时',
} as const

// 微信API错误码映射
export const WX_API_ERROR_CODES = {
  // uni.login 错误
  'login:fail': '微信登录失败，请检查网络连接',
  'login:cancel': '用户取消了微信登录',

  // uni.getUserProfile 错误
  'getUserProfile:fail': '获取用户信息失败',
  'getUserProfile:cancel': '用户拒绝授权',
  'getUserProfile:deny': '用户拒绝授权',

  // uni.getUserInfo 错误（兼容旧版本）
  'getUserInfo:fail': '获取用户信息失败',
  'getUserInfo:cancel': '用户拒绝授权',

  // 网络错误
  'request:fail': '网络请求失败，请检查网络连接',
  'timeout': '请求超时，请重试',
} as const

/**
 * 微信登录错误处理器
 */
export class WechatErrorHandler {
  /**
   * 处理微信API错误
   */
  static handleWxApiError(error: any): string {
    console.error('微信API错误:', error)

    if (typeof error === 'string') {
      return WX_API_ERROR_CODES[error as keyof typeof WX_API_ERROR_CODES] || error
    }

    if (error?.errMsg) {
      const errMsg = error.errMsg

      // 匹配错误消息
      for (const [key, message] of Object.entries(WX_API_ERROR_CODES)) {
        if (errMsg.includes(key)) {
          return message
        }
      }

      return errMsg
    }

    return '微信操作失败，请重试'
  }

  /**
   * 处理后端API错误
   */
  static handleApiError(error: any): string {
    console.error('后端API错误:', error)

    // 处理HTTP响应错误
    if (error?.response) {
      const { status, data } = error.response

      // 优先使用后端返回的错误信息
      if (data?.msg) {
        return data.msg
      }

      // 根据错误码返回友好提示
      if (data?.code && WECHAT_ERROR_CODES[data.code as keyof typeof WECHAT_ERROR_CODES]) {
        return WECHAT_ERROR_CODES[data.code as keyof typeof WECHAT_ERROR_CODES]
      }

      // 根据HTTP状态码返回提示
      if (WECHAT_ERROR_CODES[status as keyof typeof WECHAT_ERROR_CODES]) {
        return WECHAT_ERROR_CODES[status as keyof typeof WECHAT_ERROR_CODES]
      }

      return `请求失败 (${status})`
    }

    // 处理网络错误
    if (error?.message) {
      if (error.message.includes('timeout')) {
        return '请求超时，请检查网络连接'
      }
      if (error.message.includes('Network')) {
        return '网络连接失败，请检查网络设置'
      }
      return error.message
    }

    return '登录失败，请重试'
  }

  /**
   * 统一错误处理入口
   */
  static handleError(error: any, context: 'wx-api' | 'backend-api' = 'backend-api'): string {
    if (context === 'wx-api') {
      return WechatErrorHandler.handleWxApiError(error)
    }
    else {
      return WechatErrorHandler.handleApiError(error)
    }
  }

  /**
   * 显示错误提示
   */
  static showError(error: any, context: 'wx-api' | 'backend-api' = 'backend-api', duration: number = 2000) {
    const message = WechatErrorHandler.handleError(error, context)

    uni.showToast({
      title: message,
      icon: 'none',
      duration,
      mask: true,
    })
  }

  /**
   * 显示加载状态
   */
  static showLoading(title: string = '登录中...') {
    uni.showLoading({
      title,
      mask: true,
    })
  }

  /**
   * 隐藏加载状态
   */
  static hideLoading() {
    uni.hideLoading()
  }

  /**
   * 显示成功提示
   */
  static showSuccess(title: string = '登录成功', duration: number = 1500) {
    uni.showToast({
      title,
      icon: 'success',
      duration,
      mask: true,
    })
  }
}

/**
 * 微信登录重试机制
 */
export class WechatRetryHandler {
  private static readonly MAX_RETRY_COUNT = 3
  private static readonly RETRY_DELAY = 1000 // 1秒

  /**
   * 带重试的异步操作
   */
  static async withRetry<T>(
    operation: () => Promise<T>,
    maxRetries: number = this.MAX_RETRY_COUNT,
    delay: number = this.RETRY_DELAY,
  ): Promise<T> {
    let lastError: any

    for (let i = 0; i <= maxRetries; i++) {
      try {
        return await operation()
      }
      catch (error) {
        lastError = error

        // 最后一次重试失败，抛出错误
        if (i === maxRetries) {
          throw error
        }

        // 等待后重试
        await new Promise(resolve => setTimeout(resolve, delay * (i + 1)))

        console.log(`微信登录重试 ${i + 1}/${maxRetries}`)
      }
    }

    throw lastError
  }
}

/**
 * 微信登录状态管理
 */
export class WechatLoginState {
  private static _isLogging = false

  /**
   * 检查是否正在登录
   */
  static isLogging(): boolean {
    return this._isLogging
  }

  /**
   * 设置登录状态
   */
  static setLogging(logging: boolean) {
    this._isLogging = logging
  }

  /**
   * 防重复登录装饰器
   */
  static preventDuplicate<T extends any[], R>(
    fn: (...args: T) => Promise<R>,
  ): (...args: T) => Promise<R> {
    return async (...args: T): Promise<R> => {
      if (WechatLoginState.isLogging()) {
        throw new Error('正在登录中，请稍候...')
      }

      WechatLoginState.setLogging(true)
      try {
        return await fn(...args)
      }
      finally {
        WechatLoginState.setLogging(false)
      }
    }
  }
}

// 导出便捷方法
export const showWxError = WechatErrorHandler.showError
export const showWxLoading = WechatErrorHandler.showLoading
export const hideWxLoading = WechatErrorHandler.hideLoading
export const showWxSuccess = WechatErrorHandler.showSuccess
export const withWxRetry = WechatRetryHandler.withRetry
export const preventDuplicateLogin = WechatLoginState.preventDuplicate
